package com.quartet.modules.stock.controller;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.quartet.api.ApiResult;
import com.quartet.api.MapServerException;
import com.quartet.api.PageResult;
import com.quartet.api.ResultErrorEnum;
import com.quartet.modules.order.entity.TOrder;
import com.quartet.modules.order.service.TOrderService;
import com.quartet.modules.service.entity.TServiceInfo;
import com.quartet.modules.service.service.TServiceInfoService;
import com.quartet.modules.stock.dto.TFlowCardStockAddRequestDto;
import com.quartet.modules.stock.dto.TFlowCardStockQueryRequestDto;
import com.quartet.modules.stock.dto.TFlowCardStockResponseDto;
import com.quartet.modules.stock.entity.TFlowCardStock;
import com.quartet.modules.stock.entity.TTerminalStock;
import com.quartet.modules.stock.service.TFlowCardStockService;
import com.quartet.modules.stock.service.TTerminalStockService;
import com.quartet.modules.terminal.entity.TTerminalInfo;
import com.quartet.modules.terminal.service.TTerminalInfoService;
import com.quartet.utils.constant.MapServerConstant;
import com.quartet.utils.enums.InventoryStatusEnum;
import com.quartet.utils.enums.OrderStatusEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.IOUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 流量卡库存表(TFlowCardStock)表控制层
 *
 * @author makejava
 * @since 2021-06-20 09:07:33
 */
@RestController
@RequestMapping("tFlowCardStock")
@Slf4j
@Api(tags = "业务：流量卡库存管理")
public class TFlowCardStockController {
    /**
     * 服务对象
     */
    @Resource
    private TFlowCardStockService tFlowCardStockService;
    /**
     * 服务对象
     */
    @Resource
    private TOrderService tOrderService;
    /**
     * 服务对象
     */
    @Resource
    private TTerminalStockService tTerminalStockService;
    /**
     * 服务对象
     */
    @Resource
    private TTerminalInfoService tTerminalInfoService;
    /**
     * 服务对象
     */
    @Resource
    private TServiceInfoService tServiceInfoService;

    /**
     * 分页查询所有数据
     *
     * @param tFlowCardStockQueryRequestDto 查询实体
     * @return 所有数据
     */
    @PostMapping("/queryFlowCardStockPage")
    @ApiOperation("/分页查询所有流量卡数据")
    public ApiResult<PageResult<TFlowCardStockResponseDto>> queryFlowCardStockPage(@RequestBody TFlowCardStockQueryRequestDto tFlowCardStockQueryRequestDto) {
        log.info("---------queryFlowCardStockPage begin, tFlowCardStockQueryRequestDto is {}----------", tFlowCardStockQueryRequestDto);
        IPage<TFlowCardStock> page = new Page<>(tFlowCardStockQueryRequestDto.getCurrent(), tFlowCardStockQueryRequestDto.getLimit());
        QueryWrapper<TFlowCardStock> queryWrapper = new QueryWrapper<>();

        if (!ObjectUtils.isEmpty(tFlowCardStockQueryRequestDto.getInventoryStatus())) {
            queryWrapper.lambda().eq(TFlowCardStock::getInventoryStatus, tFlowCardStockQueryRequestDto.getInventoryStatus());
        }
        if (!ObjectUtils.isEmpty(tFlowCardStockQueryRequestDto.getFlowCardNumber())) {
            queryWrapper.lambda().like(TFlowCardStock::getFlowCardNumber, tFlowCardStockQueryRequestDto.getFlowCardNumber());
        }

        if (StringUtils.isNotBlank(tFlowCardStockQueryRequestDto.getField())) {
            queryWrapper.orderBy(true, tFlowCardStockQueryRequestDto.isAsc(), tFlowCardStockQueryRequestDto.getField());
        } else {
            queryWrapper.orderBy(true, tFlowCardStockQueryRequestDto.isAsc(), MapServerConstant.CREATE_TIME);
        }
        IPage<TFlowCardStock> dbResult = tFlowCardStockService.page(page, queryWrapper);
        PageResult<TFlowCardStockResponseDto> pageResult = new PageResult();
        List<TFlowCardStockResponseDto> tFlowCardStockResponseDtoList = dbResult.getRecords().stream().map(tFlowCardStock -> {
            TFlowCardStockResponseDto tFlowCardStockResponseDto = BeanUtil.copyProperties(tFlowCardStock, TFlowCardStockResponseDto.class);
            return tFlowCardStockResponseDto;
        }).collect(Collectors.toList());
        pageResult.setTotal(dbResult.getTotal());
        pageResult.setData(tFlowCardStockResponseDtoList);
        log.info("---------queryFlowCardStockPage end, data is {}----------", pageResult);
        return ApiResult.ok(pageResult);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("/getFlowCardStockById")
    @ApiOperation("/通过主键查询单条流量卡数据")
    public ApiResult<TFlowCardStockResponseDto> getFlowCardStockById(@RequestParam("id") Integer id) {
        TFlowCardStock tFlowCardStock = tFlowCardStockService.getById(id);
        TFlowCardStockResponseDto tFlowCardStockResponseDto = BeanUtil.copyProperties(tFlowCardStock, TFlowCardStockResponseDto.class);
        return ApiResult.ok(tFlowCardStockResponseDto);
    }

    /**
     * 新增数据
     *
     * @param tFlowCardStockAddRequestDto 实体对象
     * @return 新增结果
     */
    @PostMapping("/addFlowCardStock")
    @ApiOperation("/新增流量卡数据")
    public ApiResult addFlowCardStock(@RequestBody @Validated TFlowCardStockAddRequestDto tFlowCardStockAddRequestDto) {
        QueryWrapper<TFlowCardStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TFlowCardStock::getFlowCardNumber, tFlowCardStockAddRequestDto.getFlowCardNumber());
        List<TFlowCardStock> list = tFlowCardStockService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(list)) {
            throw new MapServerException(ResultErrorEnum.BMKPL001);
        }
        TFlowCardStock tFlowCardStock = BeanUtil.copyProperties(tFlowCardStockAddRequestDto, TFlowCardStock.class);
        tFlowCardStock.setStorageTime(LocalDateTime.now());
        tFlowCardStock.setInventoryStatus(InventoryStatusEnum.UNALLOCATED.getValue());
        tFlowCardStockService.save(tFlowCardStock);
        return ApiResult.ok();
    }

    /**
     * 修改数据
     *
     * @param tFlowCardStockAddRequestDto 实体对象
     * @return 修改结果
     */
    @PutMapping("/updateFlowCardStock")
    @ApiOperation("/修改流量卡数据")
    public ApiResult updateFlowCardStock(@RequestBody TFlowCardStockAddRequestDto tFlowCardStockAddRequestDto) {
        QueryWrapper<TFlowCardStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TFlowCardStock::getFlowCardNumber, tFlowCardStockAddRequestDto.getFlowCardNumber())
                .ne(TFlowCardStock::getId, tFlowCardStockAddRequestDto.getId());
        List<TFlowCardStock> list = tFlowCardStockService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(list)) {
            throw new MapServerException(ResultErrorEnum.BMKPL001);
        }
        TFlowCardStock tFlowCardStock = BeanUtil.copyProperties(tFlowCardStockAddRequestDto, TFlowCardStock.class);
        tFlowCardStockService.updateById(tFlowCardStock);
        return ApiResult.ok();
    }

    /**
     * 删除数据
     *
     * @param idList 主键集合
     * @return 删除结果
     */
    @DeleteMapping("deleteFlowCardStock")
    @ApiOperation("/删除流量卡数据")
    public ApiResult delete(@RequestBody List<Long> idList) {
        tFlowCardStockService.removeByIds(idList);
        return ApiResult.ok();
    }


    /**
     * 批量导入
     *
     * @param multipartFile 上传文件流
     * @return 删除结果
     */
    @PostMapping("/batchImportFlowCardStock")
    @ApiOperation("/批量导入流量卡数据")
    public ApiResult batchImportFlowCardStock(@RequestParam("multipartFile") MultipartFile multipartFile) throws IOException {
        tFlowCardStockService.batchImportFlowCardStock(multipartFile);
        return ApiResult.ok();
    }

    /**
     * 批量导出
     *
     * @param idList 主键集合
     * @return 删除结果
     */
    @PostMapping("/batchExportFlowCardStock")
    @ApiOperation("/批量导出流量卡数据")
    public ApiResult batchExportFlowCardStock(HttpServletRequest request, HttpServletResponse response, @RequestBody(required = false) List<Integer> idList) throws IOException {
        tFlowCardStockService.batchExportFlowCardStock(response, idList);
        return ApiResult.ok();
    }

    /**
     * 流量卡库存导入模板下载
     *
     * @param request  主键集合
     * @param response 主键集合
     * @return 下载结果
     */
    @PostMapping("/downloadExportFlowCardStockTemplate")
    @ApiOperation("/流量卡库存导入模板下载")
    public ApiResult downloadExportFlowCardStockTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //1.获取要下载的文件的绝对路径
//        String realPath = "E:\\file\\template\\流量卡库存导入模板.xls";
        String realPath = "/home/workspace/template/flow_card.xls";
        //2.获取要下载的文件名
        String fileName = realPath.substring(realPath.lastIndexOf(File.separator) + 1);
        String agent = request.getHeader("User-Agent").toUpperCase(); //获得浏览器信息并转换为大写
        byte[] bytes = agent.contains("MSIE") ? fileName.getBytes() : fileName.getBytes("UTF-8");
        // 各浏览器基本都支持ISO编码
        fileName = new String(bytes, "utf-8");
        // 文件名外的双引号处理firefox的空格截断问题
        response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
        //获取文件输入流
        InputStream in = new FileInputStream(realPath);
        OutputStream out = response.getOutputStream();
        IOUtils.copy(in, out);
        out.close();
        in.close();
        return ApiResult.ok();
    }


    /**
     * 根据客户编码查询流量卡编码
     *
     * @param customerCode
     * @return 下载结果
     */
    @GetMapping("/queryFlowCardListByCustomerCode")
    @ApiOperation("/根据客户编码查询流量卡编码")
    public ApiResult<List<String>> queryFlowCardListByCustomerCode(@RequestParam("customerCode") String customerCode,@RequestParam("serviceType") String serviceType) {

        QueryWrapper<TOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TOrder::getCustomerCode, customerCode).ne(TOrder::getPaymentStatus, OrderStatusEnum.OBSOLETE.getValue());
        List<String> orderCodeList = tOrderService.list(queryWrapper).stream().map(TOrder::getOrderCode).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(orderCodeList)) {
            return ApiResult.ok();
        }

        List<TServiceInfo> tServiceInfoList = tServiceInfoService.list(new QueryWrapper<TServiceInfo>().lambda().in(TServiceInfo::getOrderCode, orderCodeList).eq(TServiceInfo::getServiceType, serviceType));
        if (CollectionUtils.isEmpty(tServiceInfoList)){
            return ApiResult.ok();
        }

        List<String> myOrderCodeList = tServiceInfoList.stream().map(TServiceInfo::getOrderCode).collect(Collectors.toList());

        QueryWrapper<TTerminalStock> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.lambda().in(TTerminalStock::getOrderCode, myOrderCodeList);
        List<String> terminalCodeList = tTerminalStockService.list(queryWrapper1).stream().map(TTerminalStock::getTerminalCode).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(terminalCodeList)) {
            return ApiResult.ok();
        }
        QueryWrapper<TTerminalInfo> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.lambda().in(TTerminalInfo::getTerminalCode, terminalCodeList);
        List<String> flowCardNumberList = tTerminalInfoService.list(queryWrapper2).stream().map(TTerminalInfo::getFlowCardNumber).collect(Collectors.toList());
        return ApiResult.ok(flowCardNumberList);
    }
}
